<?php

namespace app\service;

use app\tool\SingletonTrait;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

class DemandOrderService
{
    use SingletonTrait;

    /**
     * 生成判断需求单是否是标准还是非标准的需求单的判断
     * @param $query
     * @param string $groupType
     * @return void
     */
    private function generateFilterWithStandardAppendField(&$query, string $groupType = '')
    {
        switch ($groupType) {
            case 'shot_standard':
                // 镜头标准
                $query->where('module_code', '=', 'shot')
                    ->where('standard_append', '=', 'yes');
                break;
            case 'shot_nonstandard':
                // 镜头非标准
                $query->where('module_code', '=', 'shot')
                    ->where('standard_append', 'IN', ['default', 'no']);
                break;
            case 'asset_standard':
                // 资产标准
                $query->where('module_code', '=', 'asset')
                    ->where('standard_append', '=', 'yes');
                break;
            case 'asset_nonstandard':
                // 资产非标准
                $query->where('module_code', '=', 'asset')
                    ->where('standard_append', 'IN', ['default', 'no']);
                break;
            default:
                break;
        }
    }

    /**
     * 使用指定需求单id按阶段分组统计实体数据
     * @param $demandOrderIds
     * @param string $countType
     * @return array
     */
    private function countEntityByDemandOrderIds($demandOrderIds, string $countType = ''): array
    {
        if (!in_array($countType, ['append', 'modify'])) {
            return [];
        }

        $reviewFeedbackEntityQuery = (new \app\model\ReviewFeedbackEntityModel)->field('stage_id,count(id) as total')
            ->where('review_feedback_id', 'IN', $demandOrderIds);

        if ($countType === 'append') {
            // 统计新增: is_append =  yes
            $reviewFeedbackEntityQuery->where('is_append', '=', 'yes');
        }

        if ($countType === 'modify') {
            // 统计返修：is_append !=  yes And enable = default
            $reviewFeedbackEntityQuery->where('is_append', '=', 'no')
                ->where('enable', '=', 'default');
        }

        $countArray = $reviewFeedbackEntityQuery->group('stage_id')->select()->toArray();
        if (empty($countArray)) {
            return [];
        }
        return array_column($countArray, 'total', 'stage_id');
    }

    /**
     * 需求变更-count
     * @param $param
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function changeCount($param): array
    {
        $appendField = [
            "count(distinct task.id) as num"
        ];
        $aboField = [
            "count(distinct task.id) as num"
        ];
        $closedId = StatusService::getInstance()->byCode('closed')['id'];

        //获取额外的sql查询条件
        $where = $this->getDemandOrderStepCategoryDefaultValueSql($param['step_category_id'] ?? []);

        //需求单新增条件
        $enableSql = join(" and ", array_filter([$where, "rfe.is_append = 'yes'"]));

        //需求单废除条件
        $appendSql = join(" and ", array_filter([$where, "rfe.enable = 'no'"]));

        // 需求单新增
        $appendData = $this->demandOrderChangeQuery($appendField, $param, $enableSql, $closedId);
        // 需求单废除
        $aboData = $this->demandOrderChangeQuery($aboField, $param, $appendSql, $closedId);

        // 需求单发起的返修
        $demandOrderRemakeData = $this->demandOrderRemake($param);

        $demandOrderReturnData['remake'] = $demandOrderRemakeData['num'] ?? 0;
        $demandOrderReturnData['append'] = $appendData['num'] ?? 0;
        $demandOrderReturnData['abo'] = $aboData['num'] ?? 0;

        return [
            'demand_order_count' => array_map('intval', $demandOrderReturnData),
            'task_work_order_count' => []
        ];
    }


    /**
     * 需求按阶段下发数据统计统计
     * @param integer $projectId 项目id
     * @param string $episodeCode 所属集数code
     * @param string $groupType 查询分组类型，shot_standard:镜头标准, shot_nonstandard:镜头非标准, asset_standard: 资产标准，asset_nonstandard: 资产非标准
     * @return array
     */
    public function countByStage(int $projectId, string $episodeCode, string $groupType = ''): array
    {
        // 1.需求单按阶段IDS stage_id > 0
        // 涉及表：review_feedback
        // 处理逻辑：
        // 仅统计需求单状态为 status = final 已经下发的需求单
        // demand_type = demand_order 需求单类型排除老数据
        // standard_append = yes 为标准新增
        $reviewFeedbackQuery = (new \app\model\ReviewFeedbackModel)->field('id')
            ->where('status', '=', 'final')
            ->where('project_id', '=', $projectId)
            ->where('demand_type', '=', 'demand_order')
            ->where('stage_id', '>', 0)
            ->whereRaw("find_in_set('{$episodeCode}', episode_codes) > 0");

        // 生成判断需求单是否是标准还是非标准的需求单的判断
        $this->generateFilterWithStandardAppendField($reviewFeedbackQuery, $groupType);

        // 获取当前查询的 stage_id 列表数据
        $demandOrderIds = $reviewFeedbackQuery->column('id');
        // 2. 统计需求单实体数量，按stage_id字段分组
        // 涉及表：review_feedback_entity
        // 需要冗余 stage_id 字段，
        // 处理逻辑：
        // 统计新增: is_append =  yes
        // 统计返修：is_append !=  yes And enable = default
        $res = [
            'append' => [], // 新增数据统计
            'modify' => [], // 返修数据统计
        ];

        if (!empty($demandOrderIds)) {
            // 统计
            $res['append'] = $this->countEntityByDemandOrderIds($demandOrderIds, 'append');
            $res['modify'] = $this->countEntityByDemandOrderIds($demandOrderIds, 'modify');
        }

        return $res;
    }


    /**
     * 需求单发起的返修
     * @param $param
     * @return array
     */
    public function demandOrderRemake($param): array
    {
        $demandOrderRemakeField = [
            "count(DISTINCT roat.task_id) as num",
        ];
//        $query = (new \app\model\NoteModel)
//            ->join('repair_order_affected_task roat', 'roat.task_repair_order_id = note.task_repair_order_id')
//            ->join('task', 'task.id = roat.task_id')
//            ->field($demandOrderRemakeField)
//            ->where('note.demand_type', 'review_feedback')
//            ->where('note.project_id', $param['project_id'])
//            ->whereBetween('roat.created', [$param['start_time'], $param['end_time']]);
        /**
         * 1.指定周期内发布的需求单
         * 2.需求单中发布后返修的任务
         */
        $query = (new \app\model\ReviewFeedbackModel)->field($demandOrderRemakeField)
            ->join('review_feedback_entity rfe', 'review_feedback.id = rfe.review_feedback_id')
            ->join('note_entity_relation', "rfe.review_feedback_id = note_entity_relation.review_feedback_id and rfe.entity_id = note_entity_relation.entity_id and note_entity_relation.relation_type = 'step_category'")
            ->join('note', 'note.id = note_entity_relation.note_id')
            ->join('repair_order_affected_task roat', 'roat.task_repair_order_id = note.task_repair_order_id')
            ->join('task', 'task.id = roat.task_id')
            ->where('rfe.published', 'yes') // 已发布
            ->where('note.demand_type', 'review_feedback')
            ->whereBetween('rfe.published_time', [$param['start_time'], $param['end_time']]);

        if (isset($param['confirm'])) {
            $query = $query->join('review_feedback_confirm', 'review_feedback_confirm.review_feedback_id = review_feedback.id', 'left');
            switch ($param['confirm']) {
                case 'yes':
                    $query->whereRaw('review_feedback_confirm.id is not null');
                    break;
                case 'no':
                    $query->whereRaw('review_feedback_confirm.id is null');
                    break;
            }
        }

        if (empty($param['step_category_id']) && empty($param['department_id'])) {
            $query->join('task_member', 'task_member.task_id = task.id', 'LEFT')
                ->where(['task_member.partner' => request()->getSaasUserId()]);
        }

        // 过滤环节
        if (!empty($param['step_category_id'])) {
            $query->whereIn('task.step_category_id', $param['step_category_id']);
        }

        if (!empty($param['project_id'])) {
            $query->where('review_feedback.project_id', $param['project_id'])
                ->where('task.project_id', $param['project_id']);
        }

        // 过滤部门
        if (!empty($param['department_id'])) {
            $departmentUserData = UserService::getInstance()->getDepartmentUserMultiDepartmentUser([$param['department_id']], request()->getTenantId());
            if (empty($departmentUserData['distinct_user_ids'])) {
                return [];
            } else {
                $distinctUserIds = $departmentUserData['distinct_user_ids'];
                $query->join('task_member', 'task_member.task_id = task.id')
                    ->whereIn('task_member.partner', $distinctUserIds);
            }
        }
        return $query->find()->toArray();

    }

    /**
     * demandOrderChangeQuery
     * @param $field
     * @param $param
     * @param $where
     * @param $closedId
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function demandOrderChangeQuery($field, $param, $where, $closedId): array
    {
        $query = (new \app\model\ReviewFeedbackModel)->field($field)
            ->join('review_feedback_entity rfe', 'review_feedback.id = rfe.review_feedback_id')
            ->join('entity', 'entity.id = rfe.entity_id', 'LEFT')
            ->join('task', 'entity.id = task.source_entity_id', 'LEFT');

        if (isset($param['confirm'])) {
            $query = $query->join('review_feedback_confirm', 'review_feedback_confirm.review_feedback_id = review_feedback.id', 'left');
            switch ($param['confirm']) {
                case 'yes':
                    $query->whereRaw('review_feedback_confirm.id is not null');
                    break;
                case 'no':
                    $query->whereRaw('review_feedback_confirm.id is null');
                    break;
            }
        }

        //如果都不给予,则筛选自己
        if (empty($param['step_category_id']) && empty($param['department_id'])) {
            $query->join('task_member', 'task_member.task_id = task.id', 'LEFT')
                ->where(['task_member.partner' => request()->getSaasUserId()]);
        }
        // 过滤环节
        if (!empty($param['step_category_id'])) {
            $query->whereIn('task.step_category_id', $param['step_category_id']);
        }

        // 过滤部门
        if (!empty($param['department_id'])) {
            $departmentUserData = UserService::getInstance()->getDepartmentUserMultiDepartmentUser([$param['department_id']], request()->getTenantId());
            if (empty($departmentUserData['distinct_user_ids'])) {
                return [];
            } else {
                $distinctUserIds = $departmentUserData['distinct_user_ids'];
                $query->join('task_member', 'task_member.task_id = task.id', 'LEFT')
                    ->whereIn('task_member.partner', $distinctUserIds);
            }
        }

        if (!empty($param['project_id'])) {
            $query->where('entity.project_id', $param['project_id'])
                ->where('task.project_id', $param['project_id']);
        }
        $query->where('task.step_type', 'step')
            ->where('rfe.published', 'yes') // 已发布
            ->whereBetween('rfe.published_time', [$param['start_time'], $param['end_time']])
            ->whereFieldRaw("get_json_string(task.`json`,'$.task_status')", '<>', $closedId);

        if (!empty($where)) {
            $query->whereRaw($where);
        }

        return $query->find()->toArray();
    }

    /**
     * @param $stepCategoryIds
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getDemandOrderStepCategoryDefaultValue($stepCategoryIds)
    {
        $result = OptionsService::getInstance()->getOptionsData("demand_order_entity_default_attribute_value");

        $stepCategoryMap = [];
        foreach ($result as $stepCategoryId => $resultItem) {
            if (in_array($stepCategoryId, $stepCategoryIds)) {
                $stepCategoryMap[$stepCategoryId] = $resultItem;
            }
        }

        return $stepCategoryMap;
    }

    /**
     * 获取默认值sql
     * @param $stepCategoryIds
     * @return string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getDemandOrderStepCategoryDefaultValueSql($stepCategoryIds)
    {
        $where = "";
        if (empty($stepCategoryIds)) {
            return $where;
        }

        $stepCategoryDefaultValueMap = $this->getDemandOrderStepCategoryDefaultValue($stepCategoryIds);

        $sql = [];
        foreach ($stepCategoryDefaultValueMap as $stepCategoryId => $item) {
            $defaultValue = $item['default'];
            $attribute = $item['attribute'];
            $sql[] = "(task.step_category_id = {$stepCategoryId} and (get_json_string(rfe.`json`,'$.{$attribute}') <> '$defaultValue' or get_json_string(rfe.`json`,'$.{$attribute}') is null ))";
        }

        if (!empty($sql)) {
            $where = "(" . join(" or ", $sql) . ")";
        }

        return $where;
    }
}
